package com.xiong.jdbc;

import com.alibaba.fastjson.JSONObject;

import java.sql.*;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class JdbcEngine {

    private Connection connection;

    public List<Map<String,Object>> selectMaps(String sql,Object...params){

        PreparedStatement statement = null;
        ResultSet resultSet=null;
        try {
            resultSet = executeQuery(statement, sql, params);
            return resultSetToMaps(resultSet);
        }finally {
            if(statement!=null){
                try {
                    statement.close();
                }catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if(resultSet!=null){
                try {
                    resultSet.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            close();
        }
    }



    public Map<String,Object> selectMap(String sql,Object...params){
        PreparedStatement statement = null;
        ResultSet resultSet=null;
        try {
            resultSet=executeQuery(statement,sql,params);
            return resultSetToMap(resultSet);
        }finally {
            if(statement!=null){
                try {
                    statement.close();
                }catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if(resultSet!=null){
                try {
                    resultSet.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            close();
        }
    }

    public int insert(String tableName,Map<String,Object> maps){
        List<Object> params=new ArrayList<>();
        StringBuilder queryBuilder = new StringBuilder();
        queryBuilder.append("INSERT INTO ").append(tableName).append(" (");
        for (String field : maps.keySet()) {
            queryBuilder.append(field).append(", ");
        }
        queryBuilder.delete(queryBuilder.length() - 2, queryBuilder.length()).append(") VALUES (");
        for (String field : maps.keySet()) {
            queryBuilder.append("?, ");
            Object obj=maps.get(field);
            params.add(obj);
        }
        queryBuilder.delete(queryBuilder.length() - 2, queryBuilder.length()).append(")");
        return execute(queryBuilder.toString(),params.toArray());
    }

    public int execute(String sql,Object ...params){
        PreparedStatement statement = null;
        try {
            return sqlExecute(statement,sql,params);
        }finally {
            if(statement!=null){
                try {
                    statement.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            close();
        }
    }

    public int[] batchExecute(String sql,List<Object[]> batchParams){
        PreparedStatement statement = null;
        try {
            return sqlBatchExecute(statement,sql,batchParams);
        }finally {
            if(statement!=null){
                try {
                    statement.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            close();
        }
    }

    /**
     * 批量更新
     * @param preparedStatement
     * @param sql
     * @param batchParams
     * @return
     */
    private int[] sqlBatchExecute(PreparedStatement preparedStatement,String sql,List<Object[]> batchParams){
        try {
            preparedStatement = connection.prepareStatement(sql);
            for (Object[] params : batchParams) {
                setParameters(preparedStatement, params);
                preparedStatement.addBatch(); // 添加到批处理中
            }
            return preparedStatement.executeBatch();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return null;
    }


    public  int sqlExecute(PreparedStatement preparedStatement,String sql,Object...params){
        try {
            preparedStatement = connection.prepareStatement(sql);
            setParameters(preparedStatement,params);
            int rowNum=preparedStatement.executeUpdate();
            return rowNum;
        }catch (Exception e){
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 新增的时候获取主键id
     * @param preparedStatement
     * @param sql
     * @param params
     * @return
     */
    private ResultSet sqlExecuteGeneratedKeys(PreparedStatement preparedStatement,String sql,Object...params) {
        try {
            preparedStatement=this.connection.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
            //设置参数
            setParameters(preparedStatement,params);
            preparedStatement.executeUpdate();
            ResultSet rs=preparedStatement.getGeneratedKeys();
            return rs;
        } catch (Exception var5) {
            var5.printStackTrace();
        }
        return null;
    }

    private List<Map<String,Object>> resultSetToMaps(ResultSet resultSet){
        try {
            List<Map<String,Object>> mapList=new ArrayList<>();
            while (resultSet.next()) {
                Map<String, Object> resultMap = new LinkedHashMap<>();
                int columnCount = resultSet.getMetaData().getColumnCount();
                for (int i = 1; i <= columnCount; i++) {
                    String columnName = resultSet.getMetaData().getColumnName(i);
                    Object columnValue = resultSet.getObject(i);
                    resultMap.put(columnName, columnValue);
                }
                mapList.add(resultMap);
            }
            return mapList;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return null;
    }

    private Map<String,Object> resultSetToMap(ResultSet resultSet){
        Map<String, Object> resultMap = new LinkedHashMap<>(); // 使用LinkedHashMap保证顺序
        try {
            while (resultSet.next()) {
                // 处理查询结果
                int columnCount = resultSet.getMetaData().getColumnCount();
                if(columnCount>1){
                    throw new Exception("存在大量数据");
                }
                for (int i = 1; i <= columnCount; i++) {
                    String columnName = resultSet.getMetaData().getColumnName(i);
                    Object columnValue = resultSet.getObject(i);
                    resultMap.put(columnName, columnValue);
                }
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultMap;
    }


    private ResultSet executeQuery(PreparedStatement statement,String sql,Object...params){
        try {
            statement = connection.prepareStatement(sql);
            setParameters(statement,params);
            // 处理查询结果
            return statement.executeQuery();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return null;
    }

    private void setParameters(PreparedStatement statement, Object... params) throws SQLException {
        for (int i = 0; i < params.length; i++) {
            statement.setObject(i + 1, params[i]);
        }
    }

    public void close(){
        if(this.connection!=null){
            try {
                this.connection.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }

    public JdbcEngine(Connection connection){
        this.connection=connection;
    }

}
